# -*- coding: utf-8 -*-
# @Author  : 影子
# @Time    : 2024/10/20 12:49
# @File    : run.py
# @Software: PyCharm
# @Description：程序运行入口
import tkinter as tk
from tkinter import filedialog

import bin.xmind_analysis as xa
import bin.excel_read_write as erw
from bin.config import read_yaml_list
from bin.logs import logger

cases_list = []

# Excel表格的表头字段
read_yaml = read_yaml_list()
headers = read_yaml.get("base_header") + read_yaml.get("customize_header")
logger.info(f"Excel表格的表头字段：{headers}")


# print(headers)


def show_basic():
    """ 显示基本信息 """""
    reset_frame()

    def outer_layer_data(sl, data, ml):
        """
        外层数据
        :param data: 用例数据
        :param sl: 目录层级数量
        :param ml: 目录层级数据
        :return:
        """
        qx = xa.data_clean(sl, data)
        for i in qx:
            _data = xa.table_arrange(ml, xa.extract_titles(i))
            cases_list.append(_data)

    def inner_layer_data(data, sl, ml):
        """
        内层数据
        :param data: 用例数据
        :param sl: 目录层级数量
        :param ml: 目录层级数据
        :return:
        """
        current_level = data.get('topics', [])
        # print(f"当前层级：{current_level}")
        for _ in range(1, sl - 1):  # 遍历到指定层级的前一级
            if not isinstance(current_level, list) or not current_level:
                print("请检查xmind文件书写规则是否正确！")
                return
            if len(current_level) == 0:  # 提前检查列表是否为空，避免后续索引错误
                print("当前层级没有子目录，请重新选择！")
                return
            current_level = current_level[0].get('topics', [])  # 假设每层只取第一个元素进入下一层

        if not isinstance(current_level, list) or not current_level:
            print("目标层级不存在或为空，请重新选择！")
            return

        listnum = len(current_level)
        for i in range(listnum):
            ml[sl - 1] = xa.extract_title_values(current_level[i])[0]  # 更新ml
            lists = current_level[i].get('topics', [])
            for j in range(len(lists)):
                _data = xa.table_arrange(ml, xa.extract_titles(lists[j]))
                cases_list.append(_data)

    def select_xmind_file():
        """
        选择xmind格式的文件
        :return:
        """
        file_path = filedialog.askopenfilename(filetypes=[("XMind files", "*.xmind")])
        if file_path:
            text_xmind_path.delete(1.0, tk.END)
            text_xmind_path.insert(tk.END, file_path)

    def main_convert():
        """ 主函数 """
        xmind_path = text_xmind_path.get("1.0", tk.END).strip()
        excel_path = xmind_path.rstrip('xmind') + 'xlsx'
        if not xmind_path:
            status_label.delete(1.0, tk.END)
            status_label.insert(tk.END, "请先选择 XMind 文件")
            return
        try:
            datas = xa.read_xmind(xmind_path)
            logger.info(f"读取XMind文件成功：{xmind_path}")
            # print(datas)
            sheet_name = datas[0]

            for _ in range(len(datas[1])):
                data = datas[1][_]
                ml = xa.extract_title_values(data)
                sl = len(ml)
                if sl == 1:
                    outer_layer_data(sl, data, ml)
                elif sl > 1:
                    inner_layer_data(data, sl, ml)
                else:
                    print("目录层级不存在或为空，请重新选择！")
            print(f"总共生成用例：{len(cases_list)} 条")
            erw.WriteExcel(sheet_name, headers, excel_path).create_write_excel(cases_list)
            logger.info(f"总共生成用例：{len(cases_list)} 条\n")
            status_label.delete(1.0, tk.END)
            status_label.insert(tk.END, f"总共转换用例：{len(cases_list)} 条\n")
            status_label.insert(tk.END, f"用例所在目录：{excel_path}")
        except Exception as err:
            print(f"Error: {err}")
            logger.error(f"Error: {err}\n")
            e = ('请确认后重试：\n'
                 '1.用例文件路径中不能有空格换行符。\n'
                 '2.检查xmind文件中不能有乱码或无法识别的字符（xmind自带表情字符除外）。\n'
                 '3.检查是否将已生成的Excel文件未关闭。\n'
                 '4.检查xmind文件书写规则和程序版本是否一致。')
            status_label.delete(1.0, tk.END)
            status_label.insert(tk.END, "转换失败：请检查Xmind文件书写规则是否正确！\n")
            status_label.insert(tk.END, f"{e}")
        finally:
            cases_list.clear()

    # 文件选择部分
    label = tk.Label(main_frame, text="Xmind路径：")
    label.config(bg='DeepSkyBlue')
    label.place(x=40, y=33)
    text_xmind_path = tk.Text(main_frame, width=30, height=2)
    text_xmind_path.config(bg='#E0FFFF')
    text_xmind_path.place(x=125, y=30)
    select_button = tk.Button(main_frame, text="选择XMind文件", command=select_xmind_file)
    select_button.config(bg='#ADD8E6')
    select_button.place(x=360, y=30)

    # 转换按钮
    convert_button = tk.Button(main_frame, text="开始转换", command=main_convert)
    convert_button.config(bg='#ADD8E6')
    convert_button.place(x=250, y=100)

    # 状态显示部分
    status_label = tk.Text(main_frame, width=75, height=12)
    status_label.config(bg='#E0FFFF')
    status_label.place(x=10, y=160)


def show_help():
    """帮助菜单"""
    reset_frame()
    help_text = """
    V1.0.3版本说明：
    1、增加日志功能，记录程序运行日志；
    2、增加配置文件，实现表头字段自定义；\n
    工具使用说明：
    1、详细使用规则可查看文件中doc文件夹下的帮助文档和示例；
    2、选择需要转换的XMind文件，点击“开始转换”按钮，即可生成Tapd用例文件；
    3、生成的Tapd用例文件会保存在同目录下的同名文件名.xlsx中；
    4、生成的用例文件中，相关信息字段均已自动填充，无需手动填写；\n
    注意事项：
    1、请勿在同一目录下生成同名文件，否则会覆盖已有文件；
    2、生成时请关闭Excel文件，否则会导致生成失败；\n
    """
    # 创建一个自定义字体对象，设置字体大小和加粗样式
    help_label = tk.Label(main_frame, text="版本描述", font=('Arial', 10), justify="left")
    help_label.place(x=0, y=0)
    help_label.config(text=help_text, bg='#E0FFFF')
    help_label.pack(fill=tk.BOTH, expand=True)


def reset_frame():
    """重置菜单框架"""
    for widget in main_frame.winfo_children():
        widget.destroy()


if __name__ == '__main__':
    # 颜色表  https://blog.csdn.net/chl0000/article/details/7657887
    root = tk.Tk()
    root.config(bg='DeepSkyBlue')
    root.title("Xmind转Tapd V1.0.3")
    root.wm_iconbitmap("./ico/xm64.ico")
    root.resizable(False, False)

    # 设置样式
    window_width = 550  # 固定窗口宽度
    window_height = 350  # 固定窗口高度

    # 自动居中计算
    screen_width = root.winfo_screenwidth()
    screen_height = root.winfo_screenheight()
    x = (screen_width - window_width) // 2
    y = (screen_height - window_height) // 2
    root.geometry(f"{window_width}x{window_height}+{x}+{y}")

    # 创建菜单栏
    menu_bar = tk.Menu(root)
    root.config(menu=menu_bar)

    # 创建功能菜单
    help_menu = tk.Menu(menu_bar, tearoff=False)
    help_menu.add_command(label="首页", command=show_basic)
    help_menu.add_command(label="关于", command=show_help)
    help_menu.add_separator()
    help_menu.add_command(label="退出", command=root.quit)

    menu_bar.add_cascade(label="帮助", menu=help_menu)

    main_frame = tk.Frame(root)
    main_frame.place(x=0, y=0, relwidth=1, relheight=1)
    main_frame.config(bg='DeepSkyBlue')

    show_basic()
    root.mainloop()
